
package simpleUnrealiableBroadcast;

import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import se.kth.ict.id2203.flp2p.FairLossPointToPointLink;
import se.kth.ict.id2203.flp2p.Flp2pDeliver;
import se.kth.ict.id2203.flp2p.Flp2pSend;
import se.sics.kompics.ComponentDefinition;
import se.sics.kompics.Handler;
import se.sics.kompics.Kompics;
import se.sics.kompics.Negative;
import se.sics.kompics.Positive;
import se.sics.kompics.Start;
import se.sics.kompics.address.Address;
import unrealiableBroadcast.UnBroadcast;
import unrealiableBroadcast.UnDeliver;
import unrealiableBroadcast.UnreliableBroadcast;

/**
 * The <code>SimpleUnreliableBroadcast</code> class.
 * 
 * @author Federico Piccinini <fpic@sics.se>
 */
public final class SimpleUnreliableBroadcast extends ComponentDefinition {

	Negative<UnreliableBroadcast> un =  provides(UnreliableBroadcast.class);	
	Positive<FairLossPointToPointLink> flp2p = requires (FairLossPointToPointLink.class);

	private static final Logger logger = LoggerFactory
			.getLogger(SimpleUnreliableBroadcast.class);

	private Set<Address> neighborSet;
	private Address self;

	/**
	 * Instantiates a new application0.
	 */
	public SimpleUnreliableBroadcast() {
		subscribe(handleInit, control);
		subscribe(handleStart, control);
		subscribe(handleUnBroadcast, un);
		subscribe(handleDeliver, flp2p);
	}

	Handler<SimpleUnreliableBroadcastInit> handleInit = new Handler<SimpleUnreliableBroadcastInit>() {
		public void handle(SimpleUnreliableBroadcastInit event) {
			logger.info("Received Init event");
			neighborSet = event.getNeighborSet();
			self = event.getSelf();
		}
	};

	Handler<Start> handleStart = new Handler<Start>() {
		public void handle(Start event) {
		}
	};

	
	Handler<UnBroadcast> handleUnBroadcast = new Handler<UnBroadcast> () {
		public void handle (UnBroadcast event) {
			for (Address neighbor : neighborSet) {
				trigger (new Flp2pSend(neighbor, event.getDeliverEvent().getMessage()), flp2p);
			}
		}
	};
	
	Handler <Flp2pDeliver> handleDeliver = new Handler<Flp2pDeliver> () {
		public void handle (Flp2pDeliver event) {
			trigger (new UnDeliver(event.getSource(), event), un);
		}
	};
	
	private void doShutdown() {
		System.out.println("2DIE");
		System.out.close();
		System.err.close();
		Kompics.shutdown();
	}
}
